home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / p063b9s.zip / UNIT / FALLBACK.PAS < prev    next >
Pascal/Delphi Source File  |  1996-06-26  |  19KB  |  636 lines

  1. UNIT FallBack;
  2. {╔══════════════════════════════════════════════════════════════════════════╗}
  3. {║ FTSC-001 Fallback                             Last changed: 26.06.96  SA ║}
  4. {║                                                                          ║}
  5. {║                         (C) Copyright 1989-96 by                         ║}
  6. {║       Dan Wulff, Jens Sandalgaard, Steen Christensen & S¢ren Ager        ║}
  7. {║                            Birger Kristensen                             ║}
  8. {║                                                                          ║}
  9. {║ This source may not be given to anybody, without the written permission  ║}
  10. {║ from The Portal Team.                                                    ║}
  11. {╚══════════════════════════════════════════════════════════════════════════╝}
  12. {$I POPDEFS.INC}
  13.  
  14. INTERFACE
  15.  
  16. USES Use32;
  17.  
  18. PROCEDURE FTSC_Sender(WaZoo: Boolean);
  19. FUNCTION  FTSC_Receiver(WaZoo: Boolean): Boolean;
  20.  
  21. IMPLEMENTATION
  22.  
  23. USES Dos, OpCrt, OpString, ApTimer,
  24.      PoPTypes, Globals, Util, StrUtil, Modem, WzSend, Com, MailUtil, Protocol,
  25.      NodeList, FileUtil, Crc, MTask, TransVid, LogFile;
  26.  
  27.   FUNCTION RecvMDM7(VAR FName: S30): Boolean;
  28.   LABEL
  29.     Top, Fubar;
  30.   VAR
  31.     Stat,TempName:S30;
  32.     RetByte:INTEGER;
  33.     i,XChkSum,
  34.     GotEoT,Tries:BYTE;
  35.   BEGIN
  36.     RecvMDM7:=FALSE;
  37.     ComPort^.SetXon(Off);
  38.     Tries:=0;
  39.     GotEoT:=0;
  40.     IF NOT ComPort^.KeyPressed THEN ComPort^.WriteByte(NAK, True);
  41. Top:
  42.     i:=0;
  43.     INC(Tries);
  44.     FILLCHAR(TempName,SizeOf(TempName),0);
  45.     FILLCHAR(FName,SizeOf(FName),0);
  46.     stat:='Que WHAT??';
  47.     WHILE ComPort^.Carrier AND (Tries<8) DO
  48.     BEGIN
  49.       RetByte:=TimedRead(3);
  50.       CASE RetByte OF
  51.         SUB : BEGIN
  52.                 IF i<>0 THEN
  53.                   IF Tries<4 THEN GOTO Top ELSE EXIT;
  54.                 XChkSum:=SUB;
  55.                 i:=1;
  56.                 WHILE TempName[i]<>#0 DO
  57.                 BEGIN
  58.                   INC(XChkSum,BYTE(TempName[i]));
  59.                   INC(i);
  60.                 END;
  61.                 ComPort^.PurgeIn;
  62.                 ComPort^.WriteByte(XChkSum, True);
  63.                 RetByte:=TimedRead(5);
  64.                 IF RetByte=ACK THEN
  65.                 BEGIN
  66.                   FName:=COPY(TempName,1,8)+'.'+COPY(TempName,9,3);
  67.                   Replace(FName,' ','',0);
  68.                   RecvMDM7:=True;
  69.                   EXIT;
  70.                 END;
  71.                 GotEoT:=0;
  72.                 ComPort^.WriteByte(NAK, True);
  73.                 GOTO Top;
  74.               END;
  75.         BYTE('u'),
  76.         ACK  : GOTO Top;
  77.         EOT  : BEGIN
  78.                  ComPort^.WriteByte(ACK, True);
  79.                  IF GotEoT>2 THEN EXIT;
  80.                  INC(GotEoT);
  81.                  GOTO Top;
  82.                END;
  83.         CAN  : BEGIN
  84.                  Stat:='Canceled by remote';
  85.                  GOTO Fubar;
  86.                END;
  87.         ELSE
  88.         BEGIN
  89.           IF RetByte<32 THEN
  90.           BEGIN
  91.             IF GotEoT>2 THEN EXIT ELSE INC(GotEoT);
  92.             ComPort^.PurgeIn;
  93.             ComPort^.WriteByte(NAK, True);
  94.             GOTO Top;
  95.           END;
  96.           IF i>=30 THEN
  97.           BEGIN
  98.             Stat:='FileName too long';
  99.             GOTO Fubar;
  100.           END;
  101.           IF (RetByte>=32) AND (RetByte<=126) THEN TempName[i]:=CHAR(RetByte);
  102.           ComPort^.WriteByte(ACK, True);
  103.         END;
  104.       END;
  105.     END;
  106. Fubar:
  107.     IF Tries>=16 THEN Stat:='FUBAR....';
  108.     AddLog('!',stat);
  109.   END;
  110.  
  111.   FUNCTION TrySEALink: Integer;
  112.   VAR
  113.     i  : BYTE;
  114.     j  : INTEGER;
  115.     t1 : EventTimer;
  116.     Ch : Byte;
  117.   BEGIN
  118.     ComPort^.PurgeIn;
  119.     FOR i:=0 TO 4 DO
  120.     BEGIN
  121.       ComPort^.WriteByte(BYTE('C'), True);
  122.       NewTimerSecs(t1, 1);
  123.       WHILE NOT TimerExpired(t1) AND ComPort^.Carrier DO
  124.         IF ComPort^.KeyPressed THEN
  125.         BEGIN
  126.           ComPort^.Peek(ch);
  127.           IF (ch=SOH) OR (ch=SYN) THEN
  128.           BEGIN
  129.             TrySEALink:=1;
  130.             EXIT;
  131.           END;
  132.           j:=TimedRead(0);
  133.           IF j=EOT THEN
  134.           BEGIN
  135.             TrySEALink:=2;
  136.             EXIT;
  137.           END ELSE
  138.             IF j=TSync THEN
  139.             BEGIN
  140.               TrySEALink:=0;
  141.               EXIT;
  142.             END;
  143.         END;
  144.     END;
  145.     TrySEALink:=0;
  146.   END;
  147.  
  148.   FUNCTION FTSC_RecvMail: Boolean;
  149.   VAR
  150.     Done:BOOLEAN;
  151.     FName:PathStr;
  152.     i,GotPacket:BYTE;
  153.     ph : TPktHeader;
  154.     pf : FILE OF TPktHeader;
  155.     Pwd : S10;
  156.   BEGIN
  157.     FTSC_RecvMail:=FALSE;
  158.     AddLog('*','Receiving inbound mail');
  159.     IF NOT ComPort^.Carrier THEN
  160.     BEGIN
  161.       AddLog('!','Other end hung up on us');
  162.       ComPort^.PurgeIn;
  163.       EXIT;
  164.     END;
  165.     AddLog(' ','Inbound mail packets');
  166.     FName:=InventPktName;
  167.     ComPort^.PurgeIn;
  168.     ComPort^.WriteByte(BYTE('C'), False);
  169.     ComPort^.WriteByte(1, False);
  170.     ComPort^.WriteByte($FE, True);
  171.     IF ReceiveFile(cfg.inbound[GlobNodeStat],FName,_b)<>0 THEN GotPacket:=1;
  172.     { Check password med videre }
  173.     ASSIGN(pf,cfg.Inbound[GlobNodeStat]+FName); FileMode:=ShareRead+ShareDenyW;
  174.     RESET(pf);
  175.     IF IORESULT=0 THEN
  176.     BEGIN
  177.       Read(pf,ph);
  178.       Close(pf);
  179.       Call.Zone:=ph.origzone;
  180.       Call.Net:=ph.orignet;
  181.       Call.Node:=ph.orignode;
  182.       Call.Point:=0;
  183.       RemapAddress(Call);
  184.       Pwd:=NodelistEntry.Password;
  185.       IF NodesRec.SessionPwd<>'' THEN Pwd:=NodesRec.SessionPwd;
  186.       IF NOT isCaller THEN AddLog(':', 'Remote is: '+NodelistEntry.SystemName+' ('+Address2Str(Call)+')');
  187.       IF Pwd<>'' THEN
  188.       BEGIN
  189.         IF Pwd<>StUpCase(AsciiZ2Str(ph.password,8)) THEN
  190.         BEGIN
  191.           AddLog('!', 'Password error: (local/remote) "'+Pwd+'"/"'+AsciiZ2Str(ph.password,8)+'"');
  192.           IF RenameFile(cfg.Inbound[GlobNodeStat]+FName,cfg.Inbound[GlobNodeStat]+ForceExtension(FName,'BAD')) THEN
  193.             AddLog('!','Mail packet renamed to '+ForceExtension(FName,'BAD'))
  194.           ELSE
  195.             AddLog('!','Mail packet '+FName+' cannot be renamed');
  196.           Exit;
  197.         END ELSE
  198.           AddLog('*', 'Password protected session');
  199.       END ELSE
  200.         IF ph.Password[1]<>#0 THEN
  201.           AddLog('#','Remote has password on you: "'+StUpCase(AsciiZ2Str(ph.password,8))+'"');
  202.     END ELSE
  203.     BEGIN
  204.       AddLog('!','Can''t open received mail packet - aborting!');
  205.       Exit;
  206.     END;
  207.     Done:=FALSE;
  208.     AddLog(' ','Inbound file attaches');
  209.     ComPort^.PurgeIn;
  210.     REPEAT
  211.       i:=TrySEALink;
  212.       IF i=0 THEN
  213.       BEGIN
  214.         IF NOT RecvMDM7(FName) THEN Done:=True ELSE
  215.           IF ReceiveFile(Cfg.Inbound[GlobNodeStat],'',TeLink)<>0 THEN
  216.           BEGIN
  217. {            Done:=True;}
  218.             ComPort^.WriteByte(ACK, True);
  219.             INC(FReceived);
  220.           END;
  221.       END ELSE
  222.         IF i=1 THEN
  223.         BEGIN
  224.           IF ReceiveFile(Cfg.Inbound[GlobNodeStat], '', _f)<>0 THEN
  225.           BEGIN
  226. {            Done:=True;}
  227.             ComPort^.WriteByte(ACK, True);
  228.             INC(FReceived);
  229.           END;
  230.         END ELSE
  231.           Done:=True;
  232.     UNTIL Done OR NOT ComPort^.Carrier;
  233.     AddLog(' ','End of inbound file attaches');
  234.     ComPort^.PurgeIn;
  235.     FTSC_RecvMail:=True;
  236.   END;
  237.  
  238.   FUNCTION GetREQStr(VAR Req:STRING): BOOLEAN;
  239.   VAR
  240.     crc,crc1,crc2:WORD;
  241.     i,j:INTEGER;
  242.   BEGIN
  243.     GetREQStr:=FALSE;
  244.     crc:=0;
  245.     i:=0;
  246.     WHILE ComPort^.Carrier DO
  247.     BEGIN
  248.       j:=TimedRead(2);
  249.       IF j<0 THEN EXIT;
  250.       IF j=ETX THEN
  251.       BEGIN
  252.         crc1:=TimedRead(2);
  253.         crc2:=TimedRead(2);
  254.         IF crc<>crc2 SHR 8 OR crc1 THEN
  255.         BEGIN
  256.           AddLog('!','Bad CRC. Trying again');
  257.           Exit;
  258.         END;
  259.         ComPort^.WriteByte(0, True);
  260.         GetREQStr:=True;
  261.         EXIT;
  262.       END ELSE
  263.       BEGIN
  264.         INC(i);
  265.         Req[i]:=CHAR(j);
  266.         crc:=UpdCRC16(j,crc);
  267.       END;
  268.     END;
  269.   END;
  270.  
  271.   PROCEDURE GenREQName(VAR Req:STRING);
  272.   VAR
  273.     pw,time,FName:S30;
  274.   BEGIN
  275.     FName:=COPY(Req,1,POS(#0,Req)-1);
  276.     Delete(Req,1,LENGTH(FName)+1);
  277.     time:=COPY(Req,1,POS(#0,Req)-1);
  278.     Delete(Req,1,LENGTH(time)+1);
  279.     pw:=COPY(Req,1,POS(#0,Req)-1);
  280.     Req:=FName;
  281.     IF pw<>'' THEN Req:=Req+' !'+pw;
  282.     Req:=Req+' +'+time;
  283.   END;
  284.  
  285.   PROCEDURE SEA_RecvReq;
  286.   VAR
  287.     t1 : EventTimer;
  288.     NeedToSendACK,Done:BOOLEAN;
  289.     j,NFiles,NFiles1:INTEGER;
  290.     Req:PathStr;
  291.   BEGIN
  292.     NewTimerSecs(t1, 20);
  293. {    IF IsCaller THEN }
  294.     BEGIN
  295.       ComPort^.WriteByte(CAN, True);
  296.       AddLog('*','Refusing inbound file request');
  297.       EXIT;
  298.     END;
  299.     AddLog(':','Inbound file request');
  300.     Done:=FALSE;
  301.     NFiles:=0;
  302.     WHILE ComPort^.Carrier AND NOT Done AND NOT TimerExpired(t1) DO
  303.     BEGIN
  304.       ComPort^.WriteByte(ENQ, True);
  305.       j:=TimedRead(2);
  306.       CASE j OF
  307.         ACK : BEGIN
  308.                 NFiles1:=NFiles;
  309.                 IF GetREQStr(Req) THEN
  310.                 BEGIN
  311.                   GenREQName(Req);
  312.                   NeedToSendACK:=True;
  313.                   SendReqFiles(2,Cfg.Addresses[Cfg.MainAdrNum].Net,Cfg.Addresses[Cfg.MainAdrNum].Node);
  314.                   IF (NFiles<0) OR (NFiles=NFiles1) THEN  { ?? }
  315.                   BEGIN
  316.                     ComPort^.WriteByte(ACK, True);
  317.                     SendFile('','',SEALink);
  318.                   END ELSE
  319.                   BEGIN
  320.                     AddLog(':',Long2Str(NFiles-NFiles1)+' Matching files sent');
  321.                   END;
  322.                 END ELSE
  323.                   IF ComPort^.Carrier THEN SendFile('','',SEALink);
  324.                 IF NFiles<0 THEN Done:=True;
  325.                 NewTimerSecs(t1, 20);
  326.               END;
  327.         ETB,
  328.         ENQ : Done:=True;
  329.         BYTE('C'),
  330.         NAK : BEGIN
  331.                 ComPort^.WriteByte(EOT, True);
  332.                 ComPort^.PurgeIn;
  333.               END;
  334.       END;
  335.     END;
  336.     AddLog(':','End of inbound file request');
  337.   END;
  338.  
  339.   PROCEDURE SEA_SendReq;
  340.   VAR
  341.     Done, Done1:BOOLEAN;
  342.     t1 : EventTimer;
  343.     ReqF, HoldName : PathStr;
  344.     sr:SEARCHREC;
  345.     tf:File;
  346.     updtime,pw,name,s,ss:STRING;
  347.     NFiles,i,j:INTEGER;
  348.     Ch : Char;
  349.  
  350.     PROCEDURE ReqOut(FName,password,UpdTime:STRING);
  351.     VAR
  352.       crc:WORD;
  353.       i:BYTE;
  354.     BEGIN
  355.       AddLog('*','Requesting '+FName);
  356.       ComPort^.WriteByte(ACK, True);
  357.       crc:=0;
  358.       FOR i:=1 TO Length(FName) DO
  359.       BEGIN
  360.         ComPort^.WriteByte(BYTE(FName[i]), False);
  361.         crc:=UpdCRC16(BYTE(FName[i]),crc);
  362.       END;
  363.       ComPort^.WriteByte(0, False);
  364.       crc:=UpdCRC16(0,crc);
  365.       FOR i:=1 TO Length(UpdTime) DO
  366.       BEGIN
  367.         ComPort^.WriteByte(BYTE(UpdTime[i]), False);
  368.         crc:=UpdCRC16(BYTE(UpdTime[i]),crc);
  369.       END;
  370.       ComPort^.WriteByte(0, False);
  371.       crc:=UpdCRC16(0,crc);
  372.       FOR i:=1 TO Length(password) DO
  373.       BEGIN
  374.         ComPort^.WriteByte(BYTE(Password[i]), False);
  375.         crc:=UpdCRC16(BYTE(Password[i]),crc);
  376.       END;
  377.       ComPort^.WriteByte(0, False);
  378.       ComPort^.WriteByte(ETX, False);
  379.       crc:=UpdCRC16(0,crc);
  380.       crc:=UpdCRC16(0,crc);
  381.       ComPort^.WriteByte(LO(crc), False);
  382.       ComPort^.WriteByte(HI(crc), True);
  383.     END;
  384.  
  385.   BEGIN
  386.     NewTimerSecs(t1, 10);
  387.     HoldName:=HoldFileName(Call,False)+'REQ';
  388.     FindFirst(HoldName,AnyFile,sr);
  389.     IF DOSERROR=0 THEN
  390.     BEGIN
  391.       AddLog(':','Outbound file request');
  392.       ASSIGN(tf,HoldName); FileMode:=ShareRead+ShareDenyW;
  393.       RESET(tf,1);
  394.       WHILE NOT EOF(tf) DO
  395.       BEGIN
  396.         ReadLine(tf,s);
  397.         s:=TrimTrail(s);
  398.         IF COPY(s,1,1)<>';' THEN
  399.         BEGIN
  400.           UpdTime:=' 0';
  401.           pw:='';
  402.           name:='';
  403.           FOR i:=1 TO wordcount(s, [' ']) DO
  404.           BEGIN
  405.             ss:=extractword(i, s, [' ']);
  406.             Ch:=ss[1];
  407.             CASE Ch OF
  408.               '!' : pw:=Copy(ss, 2, 255);
  409.               '+' : updtime:=Copy(ss, 2, 255);
  410.               ELSE IF Ch <> #0 THEN name:=ss;
  411.             END;
  412.           END;
  413.           ReqOut(Name,pw,UpdTime);
  414.           NewTimerSecs(t1, 60);
  415.           Done:=FALSE;
  416.           WHILE ComPort^.Carrier AND NOT TimerExpired(t1) AND NOT Done DO
  417.           BEGIN
  418.             j:=TimedRead(0);
  419.             IF j>=0 THEN
  420.               IF j=ACK THEN
  421.               BEGIN
  422.                 NFiles:=0;
  423.                 Done1:=FALSE;
  424.                 REPEAT
  425.                   i:=TrySEALink;
  426.                   IF i=0 THEN
  427.                   BEGIN
  428.                     IF NOT RecvMDM7(Reqf) THEN
  429.                       Done1:=True
  430.                     ELSE
  431.                       IF ReceiveFile(cfg.inbound[GlobNodeStat],'',TeLink)<>0 THEN Done1:=True ELSE
  432.                         INC(NFiles);
  433.                   END ELSE
  434.                     IF i=1 THEN
  435.                     BEGIN
  436.                       IF ReceiveFile(Cfg.Inbound[GlobNodeStat],'',_f)<>0 THEN Done1:=True ELSE
  437.                         INC(NFiles);
  438.                     END ELSE
  439.                       Done1:=True;
  440.                 UNTIL NOT ComPort^.Carrier OR Done1;
  441.                 AddLog(':','Received '+Long2Str(NFiles)+' file(s)');
  442.                 Done:=True;
  443.                 NewTimerSecs(t1, 60);
  444.                 WHILE (TimedRead(0)<>ENQ) AND NOT TimerExpired(t1) AND ComPort^.Carrier DO
  445.                   GiveUpTime;
  446.               END
  447.               ELSE
  448.               IF j=ENQ THEN ReqOut(Name,pw,UpdTime) ELSE
  449.               BEGIN
  450.                 GiveUpTime;
  451.                 IF j<>0 THEN NewTimerSecs(t1, 60);
  452.               END;
  453.           END;
  454.         END;
  455.       END;
  456.       CLOSE(tf);
  457.       DeleteFile(HoldName);
  458.     END ELSE
  459.       AddLog(':','No outbound file request');
  460.     FindClose(sr);
  461.   END;
  462.  
  463.   FUNCTION FTSC_Receiver(WaZoo: Boolean): Boolean;
  464.   LABEL
  465.     GetOut;
  466.   VAR
  467.     Done  : Boolean;
  468.     t1,t2 : EventTimer;
  469.     i,j   : Integer;
  470.     sr    : SearchRec;
  471.   BEGIN
  472.     FTSC_Receiver:=FALSE;
  473.     GlobNodeStat:=nsKnown;
  474.     IF NOT WaZoo THEN AddLog('*','Receiving mail using FTS-0001 fallback :-(');
  475.     SetUpTransferWindows(false);
  476.     ComPort^.PurgeIn;
  477.     IF NOT FTSC_RecvMail THEN GOTO GetOut;
  478.     FindFirst(HoldFileName(Call,False)+'?UT',AnyFile,sr);
  479.     IF DOSError<>0 THEN FindFirst(HoldFileName(Call,False)+'?LO',AnyFile,sr);
  480.     IF DOSError=0 THEN
  481.     BEGIN
  482.       AddLog('*','Giving mail to '+Address2Str(Call));
  483.       Done:=False;
  484.       NewTimerSecs(t1, 30);
  485.       j:=-1;
  486.       WHILE NOT TimerExpired(t1) AND ComPort^.Carrier AND NOT Done DO
  487.       BEGIN
  488.         ComPort^.WriteByte(TSync, True);
  489.         NewTimerSecs(t2, 3);
  490.         WHILE ComPort^.Carrier AND NOT TimerExpired(t2) AND NOT Done DO
  491.         BEGIN
  492.           i:=TimedRead(0);
  493.           CASE i OF
  494.             BYTE('C'),
  495.             00,
  496.             01   : IF j=BYTE('C') THEN
  497.                    BEGIN
  498.                      Done:=True;
  499.                      SendWazoo(2);
  500.                    END;
  501.             $fe  : IF j=1 THEN
  502.                    BEGIN
  503.                      Done:=True;
  504.                      SendWazoo(2);
  505.                    END;
  506.             $ff  : IF j=0 THEN
  507.                    BEGIN
  508.                      Done:=True;
  509.                      SendWazoo(2);
  510.                    END;
  511.             NAK  : IF j=NAK THEN
  512.                    BEGIN
  513.                      Done:=True;
  514.                      SendWazoo(2);
  515.                    END;
  516.             CAN,
  517.             ENQ,
  518.             SYN  : BEGIN
  519.                      Done:=True;
  520.                      AddLog('*','Remote refused to pick up mail');
  521.                    END;
  522.           END;
  523.           IF i>=0 THEN j:=i;
  524.         END;
  525.       END;
  526.       IF WaZoo THEN GOTO GetOut;
  527.       FindFirst(HoldFileName(Call,False)+'REQ',AnyFile,sr);
  528.       IF DOSError=0 THEN
  529.       BEGIN
  530.         NewTimerSecs(t1, 30);
  531.         Done:=False;
  532.         WHILE NOT TimerExpired(t1) AND ComPort^.Carrier AND NOT Done DO
  533.         BEGIN
  534.           ComPort^.WriteByte(SYN, True);
  535.           NewTimerSecs(t2, 3);
  536.           WHILE NOT TimerExpired(t2) AND ComPort^.Carrier AND NOT Done DO
  537.           BEGIN
  538.             i:=TimedRead(0);
  539.             CASE i OF
  540.               ENQ : BEGIN
  541.                       SEA_SendReq;
  542.                       Done:=True;
  543.                     END;
  544.               CAN : Done:=True;
  545.               BYTE('C'),
  546.               NAK : ComPort^.WriteByte(EOT, True);
  547.               SUB : ComPort^.WriteByte(CAN, True);
  548.             END;
  549.           END;
  550.         END;
  551.       END;
  552.       SEA_RecvReq;
  553.     END ELSE
  554.     BEGIN
  555.       AddLog('*','No mail waiting for '+Address2Str(Call));
  556.     END;
  557. GetOut:
  558.     FindClose(sr);
  559.     FTSC_Receiver:=True;
  560.     RemoveTransferWindows;
  561.     IF NOT WaZoo THEN AddLog('*','End of FTS-0001 session');
  562.   END;
  563.  
  564.   PROCEDURE FTSC_Sender(WaZoo: Boolean);
  565.   LABEL
  566.     GetOut;
  567.   VAR
  568.     t1 : EventTimer;
  569.     Ch : Byte;
  570.   BEGIN
  571.     IF Not WaZoo THEN
  572.     BEGIN
  573.       AddLog('*','Sending mail using FTS-0001 FallBack :-(');
  574.       AddLog('*', NodeListEntry.SystemName + ' ('+Address2Str(Call)+')');
  575.     END;
  576.     SetupTransferWindows(false);
  577.     SendWaZoo(2);
  578.     NewTimerSecs(t1, 10);
  579.     WHILE NOT TimerExpired(t1) AND ComPort^.Carrier DO
  580.     BEGIN
  581.       IF ComPort^.KeyPressed THEN
  582.       BEGIN
  583.         ComPort^.Peek(Ch);
  584.         CASE Ch OF
  585.           TSync : BEGIN
  586.                     ComPort^.PurgeIn;
  587.                     IF FTSC_RecvMail THEN GOTO GetOut;
  588.                     NewTimerSecs(t1, 10);
  589.                   END;
  590.           SYN   : BEGIN
  591.                     ComPort^.WriteByte(CAN, True);
  592.                     AddLog('!','Refusing inbound file requests');
  593.                     NewTimerSecs(t1, 10);
  594.                   END;
  595.           ENQ   : BEGIN
  596.                     ComPort^.PurgeIn;
  597.                     SEA_SendReq;
  598.                     GOTO GetOut;
  599.                   END;
  600.           NAK,
  601.           67    : BEGIN
  602.                     TimedRead(0);
  603.                     TimedRead(1);
  604.                     TimedRead(1);
  605.                     ComPort^.WriteByte(EOT, True);
  606.                     NewTimerSecs(t1, 10);
  607.                   END;
  608.           SUB   : BEGIN
  609.                     TimedRead(0);
  610.                     ComPort^.WriteByte(CAN, True);
  611.                   END;
  612.           ELSE    BEGIN
  613.                     TimedRead(0);
  614.                     ComPort^.WriteByte(EOT, True);
  615.                   END;
  616.         END;
  617.       END;
  618.     END;
  619.     IF NOT ComPort^.Carrier THEN
  620.     BEGIN
  621.       ComPort^.PurgeIn;
  622.       AddLog('!','Other end hung up on us <HRMPH!!>');
  623.       GOTO GetOut;
  624.     END;
  625.     IF TimerExpired(t1) THEN
  626.     BEGIN
  627.       FTSC_RecvMail;
  628.       AddLog('!','Timeout');
  629.     END;
  630. GetOut:
  631.     IF NOT WaZoo THEN AddLog(':','End of FTS-0001 session (YUCK!)');
  632.     RemoveTransferWindows;
  633.   END;
  634.  
  635. END.
  636.